package ru.mcfr.oxygen.framework.operations.table;

import ro.sync.ecss.extensions.api.*;
import ro.sync.ecss.extensions.api.content.RangeProcessor;
import ro.sync.ecss.extensions.api.node.AttrValue;
import ro.sync.ecss.extensions.api.node.AuthorDocumentFragment;
import ro.sync.ecss.extensions.api.node.AuthorElement;
import ro.sync.ecss.extensions.api.node.AuthorNode;

import javax.swing.text.BadLocationException;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: ws
 * Date: 29.03.11
 * Time: 17:18
 * To change this template use File | Settings | File Templates.
 */
public class CellsBorderOperation implements AuthorOperation {

    public void toggleAttrValue(AuthorElement ae, String attrName, String attrValue, boolean strong){

        boolean hasAttr = false;
        for (int a = 0; a < ae.getAttributesCount(); a++)
            if (ae.getAttributeAtIndex(a).equals(attrName))
                hasAttr = true;

        if (hasAttr){
            if (strong){
                if (ae.getAttribute(attrName).equals(attrValue))
                    ae.removeAttribute(attrName);
                else
                    ae.setAttribute(attrName, new AttrValue(attrValue));
            } else {
                ae.removeAttribute(attrName);
            }
        } else {
            ae.setAttribute(attrName, new AttrValue(attrValue));
        }
    }

    public void doOperation(AuthorAccess authorAccess, ArgumentsMap argumentsMap) throws IllegalArgumentException, AuthorOperationException {
        AuthorDocumentController controller = authorAccess.getDocumentController();
        String tagName = "";
        try {
            tagName = argumentsMap.getArgumentValue("название элемента").toString();
        } catch (Exception e) {
            tagName = "ячейка";
        }
        String attrName = "";
        try {
            attrName = argumentsMap.getArgumentValue("атрибут").toString();
        } catch (Exception e) {
        }
        String attrValue = "";
        try {
            attrValue = argumentsMap.getArgumentValue("значение атрибута").toString();
        } catch (Exception e) {
        }
        final String finalAttrValue = attrValue;
        final String finalAttrName = attrName;
        int caretOffset = authorAccess.getEditorAccess().getCaretOffset();
        controller.beginCompoundEdit();
        try {

            if (authorAccess.getEditorAccess().hasSelection()){
                int selStart = authorAccess.getEditorAccess().getSelectionStart();
                int selEnd = authorAccess.getEditorAccess().getSelectionEnd();

                AuthorNode blockEStart = controller.getNodeAtOffset(selStart);
                while (!blockEStart.getName().equals(tagName))
                    blockEStart = blockEStart.getParent();
                int blockStart = blockEStart.getStartOffset();

                AuthorNode blockEEnd = controller.getNodeAtOffset(selEnd);
                while (!blockEEnd.getName().equals(tagName))
                    blockEEnd = blockEEnd.getParent();
                int blockEnd = blockEEnd.getEndOffset();

                final String finalTagName = tagName;
                controller.processContentRange(blockStart, blockEnd, new RangeProcessor() {
                    @Override
                    public void processRange(AuthorDocumentFragment authorDocumentFragment) throws AuthorOperationException, BadLocationException {
                        List<AuthorNode> nodes = authorDocumentFragment.getContentNodes();
                        for (AuthorNode node : nodes){
                            if (node.getName().equals(finalTagName))
                                toggleAttrValue((AuthorElement) node, finalAttrName, finalAttrValue, false);
                            else{
                                AuthorElement[] cells = ((AuthorElement) node).getElementsByLocalName(finalTagName);
                                for (AuthorElement cell : cells)
                                    toggleAttrValue(cell, finalAttrName, finalAttrValue, false);
                            }
                        }
                    }
                });

                authorAccess.getEditorAccess().select(selStart, selEnd);

            } else {
                AuthorNode currentElement = controller.getNodeAtOffset(caretOffset);
                while (!currentElement.getName().equalsIgnoreCase(tagName))
                    currentElement = currentElement.getParent();

                controller.processContentRange(currentElement.getStartOffset(), currentElement.getEndOffset(), new RangeProcessor() {
                    @Override
                    public void processRange(AuthorDocumentFragment authorDocumentFragment) throws AuthorOperationException, BadLocationException {
                        List<AuthorNode> nodes = authorDocumentFragment.getContentNodes();
                        for (AuthorNode node : nodes)
                            toggleAttrValue((AuthorElement) node, finalAttrName, finalAttrValue, false);

                    }
                });

                authorAccess.getEditorAccess().setCaretPosition(caretOffset);
            }

        } catch (Exception e) {
            e.printStackTrace();
            authorAccess.getWorkspaceAccess().showErrorMessage(e.getMessage());
        }
        controller.endCompoundEdit();
    }

    public ArgumentDescriptor[] getArguments() {
        ArgumentDescriptor[] res = {
                new ArgumentDescriptor("название элемента", ArgumentDescriptor.TYPE_STRING, ""),
                new ArgumentDescriptor("атрибут", ArgumentDescriptor.TYPE_STRING, ""),
                new ArgumentDescriptor("значение атрибута", ArgumentDescriptor.TYPE_STRING, ""),
                new ArgumentDescriptor("режим", ArgumentDescriptor.TYPE_STRING, "все границы (true|false)"),
        };
        return res;
    }

    public String getDescription() {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }
}
